# 开发一个图形化进制转化工具，实现二进制、八进制、十进制、十六进制的相互转化

from tkinter import *
from tkinter.messagebox import *


class Exchange(Tk):
    def __init__(self):
        super().__init__()
        self.title("进制转化工具")
        self.geometry("700x350+600+400")
        self.resizable(0, 0)

        # 加载GUI
        self.setup_UI()

    def setup_UI(self):
        # 第一行选择输入的进制
        self.Label_01 = Label(self, text="选择要输入的进制：")
        self.Label_01.place(x=10, y=10)

        self.Var_radiobutton = IntVar()
        self.Var_radiobutton.set(10)  # 默认值
        self.RadioButtom_01 = Radiobutton(self,
                                          text="二进制",
                                          value=2,
                                          variable=self.Var_radiobutton)
        self.RadioButtom_01.place(x=150, y=10)

        self.RadioButtom_02 = Radiobutton(self,
                                          text="八进制",
                                          value=8,
                                          variable=self.Var_radiobutton)
        self.RadioButtom_02.place(x=250, y=10)

        self.RadioButtom_03 = Radiobutton(self,
                                          text="十进制",
                                          value=10,
                                          variable=self.Var_radiobutton)
        self.RadioButtom_03.place(x=350, y=10)

        self.RadioButtom_04 = Radiobutton(self,
                                          text="十六进制",
                                          value=16,
                                          variable=self.Var_radiobutton)
        self.RadioButtom_04.place(x=450, y=10)
        # 第二行输入数值
        self.Label_02 = Label(self, text="输入具体的数值：")
        self.Label_02.place(x=10, y=60)

        self.Var_Entry = Variable()
        self.Entry_01 = Entry(self, width=50, textvariable=self.Var_Entry)
        self.Entry_01.place(x=150, y=60)

        self.Button_01 = Button(text="计算", command=self.cal)
        self.Button_01.place(x=550, y=60)
        # 第三行显示结果
        self.Label_03 = Label(self, text="结果：")
        self.Label_03.place(x=10, y=110)

        self.Label_03_2 = Label(self, text="二进制：")
        self.Label_03_2.place(x=150, y=110)
        self.Var_Entry_2 = Variable()
        self.Entry_01_2 = Entry(self,
                                width=30,
                                textvariable=self.Var_Entry_2,
                                state=DISABLED)
        self.Entry_01_2.place(x=220, y=110)

        self.Label_03_8 = Label(self, text="八进制：")
        self.Label_03_8.place(x=150, y=170)
        self.Var_Entry_8 = Variable()
        self.Entry_01_8 = Entry(self,
                                width=30,
                                textvariable=self.Var_Entry_8,
                                state=DISABLED)
        self.Entry_01_8.place(x=220, y=170)

        self.Label_03_10 = Label(self, text="十进制：")
        self.Label_03_10.place(x=150, y=230)
        self.Var_Entry_10 = Variable()
        self.Entry_01_10 = Entry(self,
                                 width=30,
                                 textvariable=self.Var_Entry_10,
                                 state=DISABLED)
        self.Entry_01_10.place(x=220, y=230)

        self.Label_03_16 = Label(self, text="十六进制：")
        self.Label_03_16.place(x=150, y=290)
        self.Var_Entry_16 = Variable()
        self.Entry_01_16 = Entry(self,
                                 width=30,
                                 textvariable=self.Var_Entry_16,
                                 state=DISABLED)
        self.Entry_01_16.place(x=220, y=290)

    def check(self, value:int, Var_Entry:str):
        term = ["01", "01234567", "0123456789", "0123456789abcdefABCDEF"]
        temp = ""
        cov = {2: 0, 8: 1, 10: 2, 16: 3}

        # 检查开头是否有0b，0o，0x
        if Var_Entry.startswith("0b") or Var_Entry.startswith("0B"):
            if value != 2:
                showinfo("系统消息", "注意：输入为二进制，已更改输入进制为二进制")
                self.Var_radiobutton.set(2)
            Var_Entry = Var_Entry[2:]
        elif Var_Entry.startswith("0o") or Var_Entry.startswith("0O"):
            if value != 8:
                showinfo("系统消息", "注意：输入为八进制，已更改输入进制为八进制")
                self.Var_radiobutton.set(8)
            Var_Entry = Var_Entry[2:]
        elif Var_Entry.startswith("0x") or Var_Entry.startswith("0X"):
            if value != 16:
                showinfo("系统消息", "注意：输入为十六进制，已更改输入进制为十六进制")
                self.Var_radiobutton.set(16)
            Var_Entry = Var_Entry[2:]

        # 逐个检查字符是否正确
        for each in Var_Entry:
            if each in term[cov[value]]:
                temp += each
        if temp == Var_Entry:
            return True
        else:
            return False

    def cal(self):
        value = self.Var_radiobutton.get()
        Var_Entry = self.Var_Entry.get()

        # 检查输入是否正确
        if self.check(value, Var_Entry):
            # 转换为10进制
            value_temp = int(Var_Entry, value)

            # 10进制分别转换2,8,16，并去除前两位
            Var_value_2 = bin(value_temp)[2:]
            Var_value_8 = oct(value_temp)[2:]
            Var_value_10 = value_temp
            Var_value_16 = hex(value_temp)[2:]

            self.Var_Entry_2.set(Var_value_2)
            self.Var_Entry_8.set(Var_value_8)
            self.Var_Entry_10.set(Var_value_10)
            self.Var_Entry_16.set(Var_value_16)
        else:
            showinfo("系统消息", "输入错误")


if __name__ == "__main__":
    this_gui = Exchange()
    this_gui.mainloop()
